package com.mql.mall.mallauthserve.controller;

import com.alibaba.fastjson.JSON;
import com.mql.mall.mallauthserve.Entity.MemberEntity;
import com.mql.mall.mallauthserve.MemberFeign.MemberFeignService;
import com.mql.mall.mallauthserve.component.GitheeProvider;
import com.mql.mall.mallauthserve.dto.AccessTokenDTO;
import com.mql.mall.mallauthserve.dto.GiteeUser;
import com.mql.mall.mallauthserve.thirdPartyOpenFeign.SmsFeignService;
import com.mql.mall.mallauthserve.vo.UserLoginVo;
import com.mql.mall.mallauthserve.vo.UserRegisterVo;
import com.mql.mall.mallcommon.constant.AuthServerConstant;
import com.mql.mall.mallcommon.utils.R;
import io.swagger.models.auth.In;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.RandomStringUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.shiro.session.Session;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.bind.BindResult;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;

import javax.servlet.http.HttpSession;
import javax.validation.Valid;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
import java.util.stream.Stream;

@Controller
@Slf4j
public class LoginController {
    @Autowired
    private SmsFeignService smsFeignService;
    @Autowired
    private StringRedisTemplate stringRedisTemplate;
    @Autowired
    MemberFeignService memberFeignService;
    @Autowired
    private AccessTokenDTO accessTokenDTO;
    @Autowired
    private GitheeProvider githeeProvider;
    @GetMapping("/login.html")
    public String loginPage(){
        return "login";
    }
    @GetMapping("/reg.html")
    public String regPage(){
        return "reg";
    }
    @GetMapping("/sms/sendCode")
    @ResponseBody
    public R sendCode(@RequestParam("mobile")String mobile){
        String redisCode = stringRedisTemplate.opsForValue().get(AuthServerConstant.SMS_CODE_CACHE_PREFIX + mobile);
        if (!StringUtils.isEmpty(redisCode)){
            long l = Long.parseLong(redisCode.split("_")[1]);
            if(System.currentTimeMillis()-l<60000){
                return R.error(10002,"短信验证码频率太高");
            }
        }
        String code=this.messageCheck()+"_"+System.currentTimeMillis();
        stringRedisTemplate.opsForValue().set(AuthServerConstant.SMS_CODE_CACHE_PREFIX+mobile,code,30, TimeUnit.MINUTES);
        R result = smsFeignService.sendSms(mobile,code.split("_")[0]);
        return result;
    }
    public String messageCheck(){
        //五位随机数字
        String random= RandomStringUtils.randomNumeric(5);
        return random;
    }

    /**
     * //TODO 重定向是用的session，分布式session以后解决
     * @param userRegisterVo
     * @param result
     * @param redirectAttributes
     * @return
     */
    @PostMapping("/register")
    public String register(@Validated UserRegisterVo userRegisterVo, BindingResult result, RedirectAttributes redirectAttributes){
        if (result.hasErrors()){
//            Map<String,String> errors=new HashMap<>();
//            result.getFieldErrors().stream().map(fieldError -> {
//                String field = fieldError.getField();
//                String defaultMessage = fieldError.getDefaultMessage();
//                errors.put(field, defaultMessage);
//                return errors;
//            });
            Map<String, String> errors = result.getFieldErrors()
                    .stream()
                    .collect(Collectors.toMap(FieldError::getField, FieldError::getDefaultMessage));
            redirectAttributes.addFlashAttribute("errors",errors);
            //校验出错，回到注册页
            return "redirect:http://192.168.0.26:20001/reg.html";
        }
        //真正的注册功能
        //1、校验验证码
        String code = userRegisterVo.getCode();
        String redisCode = stringRedisTemplate.opsForValue().get(AuthServerConstant.SMS_CODE_CACHE_PREFIX + userRegisterVo.getPhone());
        if (!StringUtils.isEmpty(redisCode)){
            if (code.equals(redisCode.split("_")[0])){

                //校验通过之后删除验证码(令牌机制)
                stringRedisTemplate.delete(AuthServerConstant.SMS_CODE_CACHE_PREFIX + userRegisterVo.getPhone());

                //验证码通过.//远程调用注册
                R register = memberFeignService.register(userRegisterVo);
                if ((Integer)register.get("code")==0){
                    //成功返回登录页
                    return "redirect:http://192.168.0.26:20001/login.html";
                }else {
                    //失败返回注册页
                    Map<String,String> errors=new HashMap<>();
                    errors.put("msg",(String) register.get("msg"));
                    redirectAttributes.addFlashAttribute("errors",errors);
                    return "redirect:http://192.168.0.26:20001/reg.html";
                }

            }else {
                Map<String,String> errors=new HashMap<>();
                errors.put("code","验证码错误");
                redirectAttributes.addFlashAttribute("errors",errors);
                //校验出错，回到注册页
                return "redirect:http://192.168.0.26:20001/reg.html";
            }
        }else {
            Map<String,String> errors=new HashMap<>();
            errors.put("code","验证码错误");
            redirectAttributes.addFlashAttribute("errors",errors);
            //校验出错，回到注册页
            return "redirect:http://192.168.0.26:20001/reg.html";
        }
    }
    @PostMapping("/login")
    public String login(UserLoginVo userLoginVo,HttpSession session){
        R login = memberFeignService.login(userLoginVo);
        if ((Integer)login.get("code")==0){
            Object data =  login.get("data");
            session.setAttribute("user",data);
            log.info(data.toString());
            return "redirect:http://192.168.0.26:4012/";
        }else {
            Map<String,String> errors=new HashMap<>();
            errors.put("msg",(String) login.get("msg"));
            session.setAttribute("errors",errors);
            return "redirect:http://192.168.0.26:20001/login.html";
        }
    }
    @GetMapping("/callback")
    public String callback(@RequestParam(name = "code") String code,
                           @RequestParam(name = "state") String state,
                           HttpSession session){
        accessTokenDTO.setClient_id("66486c68e0efe747c0bc25b2a0adc67da70a5fc010e633a0f70f7c1999d9e10b");
        accessTokenDTO.setClient_secret("4dd0ecbf8aab285a2083a01ff714c236a0e76e030c5568741f24714a972017c3");
        accessTokenDTO.setRedirect_uri("http://192.168.0.26:20001/callback");
        accessTokenDTO.setCode(code);
        accessTokenDTO.setState(state);
        String token = githeeProvider.getAccessToken(accessTokenDTO);
        GiteeUser giteeUser = githeeProvider.getGiteeUser(token);
        System.out.println("id  :"+giteeUser.getId());
        System.out.println("name  :"+giteeUser.getName());
        System.out.println("bio  :"+giteeUser.getBio());
        MemberEntity memberEntity=new MemberEntity();
        memberEntity.setNickname("gitee_"+giteeUser.getId()+giteeUser.getName());
        R thirdRegister = memberFeignService.thirdRegister(memberEntity);
        if ((Integer) thirdRegister.get("code")==0){
            //成功返回登录页
            session.setAttribute("user",JSON.toJSON(memberEntity));
            log.info(memberEntity.toString());
            return "redirect:http://192.168.0.26:4012/";
        }else {
            return "redirect:http://192.168.0.26:20001/login.html";
        }
    }
}
